package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"smart-health-platforms/config"
	"smart-health-platforms/pkg"
	"strconv"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
)

// 健康报告结构体定义
type HealthReport struct {
	UserID          uint64           `json:"user_id"`          // 用户ID
	RecordCount     int              `json:"record_count"`     // 记录总数
	TimeRange       TimeRange        `json:"time_range"`       // 测量时间范围
	Temperature     TemperatureStats `json:"temperature"`      // 体温统计
	HealthAdvice    []string         `json:"health_advice"`    // 健康建议
	DetailedRecords []DetailedRecord `json:"detailed_records"` // 详细记录
	CreatedAt       string           `json:"created_at"`       // 报告生成时间
}

// 时间范围（最早/最晚测量时间）
type TimeRange struct {
	Earliest string `json:"earliest"` // 最早时间（可读格式）
	Latest   string `json:"latest"`   // 最晚时间（可读格式）
}

// 统计（最高/最低/平均）
type TemperatureStats struct {
	Max   float32 `json:"max"`   // 最高体温（°C）
	Min   float32 `json:"min"`   // 最低体温（°C）
	Avg   float32 `json:"avg"`   // 平均体温（°C）
	Unit  string  `json:"unit"`  // 单位（固定为°C）
	Trend string  `json:"trend"` // 体温趋势（上升/下降/平稳）
}

// 详细记录
type DetailedRecord struct {
	RecordID       int     `json:"record_id"`       // 记录ID（_id）
	DeviceID       uint64  `json:"device_id"`       // 设备ID
	CollectionTime string  `json:"collection_time"` // 采集时间（可读格式）
	Temperature    float32 `json:"temperature"`     // 体温值（°C）
	Status         string  `json:"status"`          // 状态（正常/偏高/偏低）
}

// 从MongoDB查询用户的体温记录
func queryTemperatureRecords(userID uint64, name string) ([]bson.M, error) {
	// 获取集合
	collection := config.HealthDB.Collection(name)
	// 构建查询条件
	filter := bson.M{"user_id": userID}
	// 按时间排序
	sort := bson.M{"collection_time": 1}
	// 执行查询
	cursor, err := collection.Find(
		context.Background(),
		filter,
		options.Find().SetSort(sort),
	)
	if err != nil {
		pkg.Warn("查询数据失败")
		return nil, fmt.Errorf("查询数据失败: %w", err)
	}
	defer cursor.Close(context.Background())
	// 解析结果
	var records []bson.M
	if err := cursor.All(context.Background(), &records); err != nil {
		pkg.Warn("解析查询结果失败")
		return nil, fmt.Errorf("解析查询结果失败: %w", err)
	}
	return records, nil
}

// 生成健康建议
func generateHealthAdvice(stats TemperatureStats, records []DetailedRecord) []string {
	var advice []string
	// 基础体温建议
	advice = append(advice, "正常人体温一般在36.0°C-37.2°C之间，体温会受到环境、活动等因素影响。")
	// 根据平均体温给出建议
	if stats.Avg > 37.3 {
		advice = append(advice, "您的平均体温偏高，可能存在轻微发热，请注意休息，多喝温水。")
		if stats.Avg > 38.5 {
			advice = append(advice, "体温超过38.5°C，建议及时就医检查。")
		}
	} else if stats.Avg < 36.0 {
		advice = append(advice, "您的平均体温偏低，请注意保暖，避免受凉。")
	} else {
		advice = append(advice, "您的平均体温在正常范围内，继续保持良好的生活习惯。")
	}
	// 根据体温趋势给出建议
	switch stats.Trend {
	case "上升":
		advice = append(advice, "您的体温呈上升趋势，请注意观察身体状况变化。")
	case "下降":
		advice = append(advice, "您的体温呈下降趋势，情况正在好转。")
	default:
		advice = append(advice, "您的体温保持稳定，状态良好。")
	}
	// 通用健康建议
	advice = append(advice, "建议保持规律作息，均衡饮食，适当运动，增强免疫力。")
	return advice
}

// 生成心率健康建议
func generateHRHealthAdvice(stats TemperatureStats, records []DetailedRecord) []string {
	var advice []string

	// 基础心率知识
	advice = append(advice, "正常成年人静息心率一般在60-100次/分钟，运动员可能偏低（50-60次/分钟）。")

	// 根据平均心率给出建议
	if stats.Avg > 100 {
		advice = append(advice, "您的平均心率偏高，可能存在心动过速，建议避免剧烈运动，注意休息。")
		if stats.Avg > 120 {
			advice = append(advice, "心率持续超过120次/分钟，建议及时就医检查。")
		}
	} else if stats.Avg < 60 {
		advice = append(advice, "您的平均心率偏低，若为运动员或长期锻炼者属正常，否则建议关注是否有头晕等症状。")
		if stats.Avg < 50 {
			advice = append(advice, "心率持续低于50次/分钟，建议咨询医生进行评估。")
		}
	} else {
		advice = append(advice, "您的平均心率在正常范围内，继续保持良好的生活习惯。")
	}

	// 根据心率趋势给出建议
	switch stats.Trend {
	case "上升":
		advice = append(advice, "您的心率呈上升趋势，请注意是否有过度疲劳或压力过大的情况。")
	case "下降":
		advice = append(advice, "您的心率呈下降趋势，若伴随规律锻炼属正常，否则请关注身体变化。")
	default:
		advice = append(advice, "您的心率保持稳定，状态良好。")
	}

	// 通用健康建议
	advice = append(advice, "建议保持规律作息，适度运动，避免过度劳累，保持心情舒畅。")

	return advice
}

// 生成健康报告
func GenerateReport(userID uint64, name string) (*HealthReport, error) {
	// 1. 查询用户的体温记录
	records, err := queryTemperatureRecords(userID, name)
	if err != nil {
		// 将logx.Error改为pkg.Warn，保持参数不变
		pkg.Warn("查询用户体温记录失败", zap.Uint64("user_id", userID), zap.Error(err))
		return nil, err
	}
	// 2. 处理记录数据
	detailedRecords := make([]DetailedRecord, 0, len(records))
	var totalTemp float32
	var maxTemp, minTemp float32
	for i, record := range records {
		// 解析时间戳
		tsStr, ok := record["collection_time"].(string)
		if !ok {
			continue
		}
		ts, err := strconv.ParseInt(tsStr, 10, 64)
		if err != nil {
			continue
		}
		formattedTime := time.Unix(ts, 0).Format("2006-01-02 15:04:05")
		// 解析体温值
		temp, ok := record["result"].(float64)
		if !ok {
			continue
		}
		temp32 := float32(temp)
		// 计算总和、最大值、最小值
		totalTemp += temp32
		if i == 0 || temp32 > maxTemp {
			maxTemp = temp32
		}
		if i == 0 || temp32 < minTemp {
			minTemp = temp32
		}
		// 判断体温状态
		var status string
		if temp32 > 37.3 {
			status = "偏高"
		} else if temp32 < 36.0 {
			status = "偏低"
		} else {
			status = "正常"
		}
		// 构建详细记录
		detailedRecords = append(detailedRecords, DetailedRecord{
			RecordID:       int(record["_id"].(int32)),
			DeviceID:       uint64(record["device_id"].(int64)),
			CollectionTime: formattedTime,
			Temperature:    temp32,
			Status:         status,
		})
	}
	recordCount := len(detailedRecords)
	// 4. 计算统计数据
	avgTemp := totalTemp / float32(recordCount)
	/*	trend := analyzeTemperatureTrend(detailedRecords)*/
	// 5. 生成时间范围
	timeRange := TimeRange{
		Earliest: detailedRecords[0].CollectionTime,
		Latest:   detailedRecords[recordCount-1].CollectionTime,
	}
	// 6. 生成健康建议
	healthAdvice := generateHealthAdvice(TemperatureStats{
		Max:  maxTemp,
		Min:  minTemp,
		Avg:  avgTemp,
		Unit: "°C",
		//Trend: trend,
	}, detailedRecords)
	// 7. 构建完整报告
	report := &HealthReport{
		UserID:      userID,
		RecordCount: recordCount,
		TimeRange:   timeRange,
		Temperature: TemperatureStats{
			Max:  maxTemp,
			Min:  minTemp,
			Avg:  avgTemp,
			Unit: "°C",
			//Trend: trend,
		},
		HealthAdvice:    healthAdvice,
		DetailedRecords: detailedRecords,
		CreatedAt:       time.Now().Format("2006-01-02 15:04:05"),
	}
	return report, nil
}

// 保存健康报告到文件
func SaveReportToFile(report *HealthReport, dir string) (string, error) {
	// 确保目录存在
	if err := os.MkdirAll(dir, 0755); err != nil {
		return "", fmt.Errorf("创建目录失败: %w", err)
	}

	// 生成文件名 (userID_时间戳.json)
	timestamp := time.Now().Unix()
	filename := fmt.Sprintf("health_report_%d_%d.json", report.UserID, timestamp)
	filePath := filepath.Join(dir, filename)

	// 序列化报告为JSON
	data, err := json.MarshalIndent(report, "", "  ")
	if err != nil {
		return "", fmt.Errorf("序列化报告失败: %w", err)
	}

	// 写入文件
	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return "", fmt.Errorf("写入文件失败: %w", err)
	}

	return filePath, nil
}

// 生成并保存健康报告
func GenerateAndSaveReport(userID uint64, dir string, name string) (*HealthReport, string, error) {
	// 生成报告
	report, err := GenerateReport(userID, name)
	if err != nil {
		return nil, "", err
	}

	// 保存报告
	filePath, err := SaveReportToFile(report, dir)
	if err != nil {
		return report, "", err
	}

	return report, filePath, nil
}
